package com.sss.gsb.orm.repository;

import java.math.BigDecimal;
import java.text.MessageFormat;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.hibernate.Query;
import org.hibernate.Session;
/**
 * 
 * @author PraditR
 *
 * @param <T>
 */
public abstract class BaseRepository <T> implements IBaseRepository <T>  {

	private static final String SELECT_STM = "select c from {0} c";
	@PersistenceContext
	private EntityManager em;
	
	protected abstract Class<T> getPersistantClass();	
	
	@Override
	public void delete(Integer pk) {		
		em.remove(this.findByPrimaryKey(pk));
	}
	@Override
	public void delete(BigDecimal pk) {
		em.remove(this.findByPrimaryKey(pk));
	}
	@Override
	public void delete(T t) {		
		em.remove(t);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<T> findAll() {		
		return (List<T>)em.createQuery(MessageFormat.format(SELECT_STM, getPersistantClass().getSimpleName())).getResultList();
	}

	@Override
	public T findByPrimaryKey(Integer pk) {		
		return em.find(getPersistantClass(),pk);
	}
	
	public T findByPrimaryKey(BigDecimal pk) {		
		return em.find(getPersistantClass(),pk);
	}

	@Override
	public void insert(T t) {	
		em.persist(t);
	}

	@Override
	public T update(T t) {		
		return em.merge(t);
	}
	
	public void refresh(T t){
		em.refresh(t);
		
	}
	
	protected Query findByNamedQuery(String name) {
		return getCurrentSession().getNamedQuery(name);
	}


	protected Session getCurrentSession() {
		Object delegate = em.getDelegate();

		if (!(delegate instanceof Session)) {
			throw new UnsupportedOperationException(
					"EntityManager != Hibernate Session");
		}

		Session session = (Session)delegate;
		return session;
	}

	
	public void enableFilter(String filterName, Map<String, Object> parameters) {
		org.hibernate.Filter filter = this.getCurrentSession().enableFilter(filterName);
		for(String key : parameters.keySet()){
			filter.setParameter(key, parameters.get(key));
		}
		
	}
	
	public void enableFilter(String filterName) {
		this.getCurrentSession().enableFilter(filterName);
	}

	public void disableFilter(String filterName) {
		this.getCurrentSession().disableFilter(filterName);
	}
	
	protected void mapQueryParameter(Map<String, Object> param, Query query) {
		for (String key : param.keySet()) {
			query.setParameter(key, param.get(key));
		}
	}
}
